package com.by.ioc;

/**
 * @version 1.0
 * @Author 彭彦彬
 * @Date 2025/4/9 9:56
 * @注释
 */
import com.by.annotion.MyAutowired;
import com.by.annotion.MyComponent;

import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Enumeration;

public class MyApplicationContext {
    private Map<String, Object> beanMap = new HashMap<>();

    public void registerBean(String beanName, Object bean) {
        beanMap.put(beanName, bean);
    }

    public Object getBean(String beanName) {
        System.out.println("Registered beans: " + beanMap.keySet());
        for (String key : beanMap.keySet()) {
            if (key.equalsIgnoreCase(beanName)) {
                return beanMap.get(key);
            }
        }
        return null;
    }

    public void scanPackage(String basePackage) throws Exception {
        String packagePath = basePackage.replace(".", "/");
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Enumeration<URL> resources = classLoader.getResources(packagePath);

        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            File directory = new File(resource.getFile());
            File[] files = directory.listFiles();

            if (files == null) continue;

            for (File file : files) {
                if (file.isDirectory()) {
                    scanPackage(basePackage + "." + file.getName());
                } else {
                    String className = basePackage + "." + file.getName().replace(".class", "");
                    Class<?> clazz = Class.forName(className);
                    if (clazz.isAnnotationPresent(MyComponent.class)) {
                        String beanName = clazz.getSimpleName().toLowerCase();
                        System.out.println("Registering bean: " + beanName);
                        Object instance = clazz.getDeclaredConstructor().newInstance();
                        registerBean(beanName, instance);
                    }
                }
            }
        }
    }

    public void autowire() throws Exception {
        for (Map.Entry<String, Object> entry : beanMap.entrySet()) {
            Object bean = entry.getValue();
            System.out.println("Processing bean: " + entry.getKey());
            for (Field field : bean.getClass().getDeclaredFields()) {
                if (field.isAnnotationPresent(MyAutowired.class)) {
                    field.setAccessible(true);
                    String fieldName = field.getName();
                    System.out.println("Injecting dependency for field: " + fieldName);
                    Object dependency = getBean(fieldName);
                    if (dependency == null) {
                        System.out.println("Dependency not found for field: " + fieldName);
                    } else {
                        field.set(bean, dependency);
                        System.out.println("Dependency injected successfully: " + fieldName);
                    }
                }
            }
        }
    }
}